/**
 * OSAmI: Open Source Ambient Intelligence
 * Copyright (C) 2010 Bull S.A.S.
 * Contact: osami-general@osami-commons.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 * --------------------------------------------------------------------------
 * $Id: ListIdentitiesOperation.java 342 2010-12-07 10:20:47Z osami.fr $
 * --------------------------------------------------------------------------
 */


package org.osami.gateway.display.internal.identity;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Instantiate;
import org.apache.felix.ipojo.annotations.Provides;
import org.apache.felix.ipojo.annotations.Requires;
import org.osami.gateway.display.internal.ServletPaths;
import org.osami.gateway.identity.Identity;
import org.osami.gateway.identity.IdentityManager;

/**
 * A {@code ListIdentitiesOperation} is ...
 *
 * @author Guillaume Sauthier
 */
@Component
@Provides
@Instantiate
public class ListIdentitiesOperation implements WebOperation {

    public static final String PATTERN = "/list";

    @Requires
    private IdentityManager manager;

    public String getRecognizedPattern() {
        return PATTERN;
    }

    public void execute(final HttpServletRequest request,
                        final HttpServletResponse response,
                        final Map<String, String> urlParameters)
            throws ServletException, IOException {

        PrintWriter writer = response.getWriter();

        writer.println("<html lang='en'>");

        // HTML Head
        // ---------------------------------------------------
        writer.println("<head>");
        writer.println("<title>Managed Identities at " + new Date() + "</title>");
        writer.println("<link href=\"/resource/css/designSensor.css\" rel=\"stylesheet\" type=\"text/css\" />");
        writer.println("</head>");

        // HTML Body
        // ---------------------------------------------------
        writer.println("<body>");

        printPageTitle(writer);
        printIdentitiesTable(writer);

        writer.println("<hr/>");
        writer.println("<a href=\"" + IdentitiesServlet.IDENTITY + "\">Go back to main identity page</a><br />");
        writer.println("<a href=\"" + ServletPaths.INDEX + "\">Go back to main page</a>\n");
        writer.println("</body>");

        writer.println("</html>");
    }

    private void printPageTitle(PrintWriter writer) {
        writer.println("<h1>Managed Identities</h1><hr/>\n");
    }

    private void printIdentitiesTable(PrintWriter writer) {
        writer.println("<table width='100%' cellpadding='0'>");
        // Print table headers
        writer.println("<thead><tr>");
        // Print each column name here
        printIdentityTableHeaders(writer);
        writer.println("</tr></thead>");

        // Print table body
        writer.println("<tbody>");
        // Print each alarm in its own row
        for (Identity identity : this.manager.getIdentities(null)) {
            printIdentityRow(writer, identity);
        }
        writer.println("</tbody>");
        writer.println("</table>");
    }

    private void printIdentityTableHeaders(PrintWriter writer) {
        writer.println("<th>ID</th>");
        writer.println("<th>Details</th>");
        writer.println("<th>Operations</th>");
    }

    private void printIdentityRow(PrintWriter writer, Identity identity) {
        writer.println("<tr>");
        String href = IdentitiesServlet.IDENTITY + "/" + identity.getIdentityID() + IdentityDetailsOperation.PATTERN;
        printTableCell(writer, anchor(href, identity.getIdentityID()));
        printTableCell(writer, identity.getMergedProperties().toString());
        printTableCell(writer, printOperations(identity));
        writer.println("</tr>");
    }

    private String anchor(String href, String message) {
        return "<a href='" + href + "'>" + message + "</a>";
    }

    private String printOperations(Identity identity) {
        StringBuilder sb = new StringBuilder();

        if (Identity.State.UNBOUND.equals(identity.getState())) {
            // Unbound Identity
            printBindForm(sb, identity);
        } else {
            // Bound identity
            printUnbindForm(sb, identity);
        }

        // TODO print the remove link

        return sb.toString();
    }

    private void printUnbindForm(StringBuilder sb, Identity identity) {
        String action = IdentitiesServlet.IDENTITY + "/" + identity.getIdentityID() + UnbindIdentityOperation.PATTERN;
        String boundId = identity.getBoundIdentifier();
        sb.append("<form method='GET' action='").append(action).append("'>");
        sb.append("  <input name='bound-identifier' disabled='true' type='text' size='20' value='")
                .append(boundId)
                .append("'/>");
        sb.append("  <input type='submit' value='Unbind' />");
        sb.append("</form>");
    }

    private void printBindForm(StringBuilder sb, Identity identity) {
        String action =IdentitiesServlet.IDENTITY + "/" + identity.getIdentityID() + BindIdentityOperation.PATTERN;
        sb.append("<form method='GET' action='").append(action).append("'>");
        sb.append("  <input name='bound-identifier' type='text' size='20' />");
        sb.append("  <input type='submit' value='Bind' />");
        sb.append("</form>");
    }

    private void printTableCell(PrintWriter writer, String content) {
        writer.println("<td>" + content + "</td>");
    }

}
